/***************************************************************************
 *   Copyright (C) 2009 by Marian Skvarek   *
 *   skvarek.marian@gmail.com   *
 *                                                                         *
 *   This program is free software; you can redistribute it and/or modify  *
 *   it under the terms of the GNU General Public License as published by  *
 *   the Free Software Foundation; either version 2 of the License, or     *
 *   (at your option) any later version.                                   *
 *                                                                         *
 *   This program is distributed in the hope that it will be useful,       *
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
 *   GNU General Public License for more details.                          *
 *                                                                         *
 *   You should have received a copy of the GNU General Public License     *
 *   along with this program; if not, write to the                         *
 *   Free Software Foundation, Inc.,                                       *
 *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
 ***************************************************************************/
#include "CNoteGroupView.h"
#include "CNoteGroup.h"
#include "CBar.h"
#include "CNote.h"
#include "CNoteView.h"
#include "CDebug.h"
#include "CGlobals.h"
#include "CResources.h"

#include <QGraphicsSceneHoverEvent>
#include <QBrush>

using namespace easyscore::utils;
using namespace easyscore::globals;

namespace easyscore
{
    namespace core
    {

        CNoteGroupView::CNoteGroupView ( CNoteGroup *model ) : CSymbolView ( model )
        {
            mModel = model;

            //setAcceptHoverEvents ( true );
            setZValue ( 64 );
        }

        void CNoteGroupView::initialize()
        {
            CSymbolView::initialize();

            mStem.setParentItem ( this );
            mStem.setZValue ( zValue() + 1 );

            int x1= (rect().width() - 120)/2;
            for(int i = 0; i < 5; ++i)
            {
                mUpperLines[i].setParentItem(this);
                mUpperLines[i].setVisible(false);
                mUpperLines[i].setLine(x1,80*(i + 1),x1 + 120,80*(i + 1));
                mUpperLines[i].setZValue(zValue() + 1);

                mLowerLines[i].setParentItem(this);
                mLowerLines[i].setVisible(false);
                mLowerLines[i].setLine(x1,80*(i + 11),x1 + 120,80*(i + 11));
                mLowerLines[i].setZValue(zValue() + 1);

                mRightFlags[i].setParentItem(this);
                mRightFlags[i].setVisible(false);
                mRightFlags[i].setPixmap(CResources::getInstance()->getRightFlagPixmap());
                mRightFlags[i].setZValue(zValue() + 1);

                mLeftFlags[i].setParentItem(this);
                mLeftFlags[i].setVisible(false);
                mLeftFlags[i].setPixmap(CResources::getInstance()->getLeftFlagPixmap());
                mLeftFlags[i].setZValue(zValue() + 1);
            }

            QAction *removeAction = mMenu.addAction("Remove");
            QObject::connect(removeAction, SIGNAL(triggered()),
                             this, SLOT(remove()));


            mMenu.addSeparator();

            update();
        }

        void CNoteGroupView::clear()
        {
            CSymbolView::clear();
        }

        CNoteGroupView::~CNoteGroupView()
        {
            clear();
        }

        //        void CNoteGroupView::hoverEnterEvent( QGraphicsSceneHoverEvent *event)
        //        {
        //            Q_UNUSED(event);

        //            setBrush(QColor(50,50,50,50));
        //        }

        void CNoteGroupView::hoverMoveEvent ( QGraphicsSceneHoverEvent *event )
        {
            const int u = CGlobals::getUnitSymbolWidth() / 2;
            const int y = event->pos().y();


            if(y <= 120)
                return;

            const int pos = 30 - ((y - 121) / u);


            if(!mModel->getParentPart()->isPositionOK(pos))
                return;

            //QString t = QString::number(y) + "," + QString::number(pos);
            //CDebug::getInstance()->showDebugText(t);

            if ( !mModel->hasTemporaryNote() )
            {
                if(mModel->getParentPart()->maxNoteCount() >  mModel->getNoteCount())
                {
                    mModel->insertTemporaryNote ( pos );
                }
            }
            else
            {
                mModel->getTemporaryNote()->setPosition (  pos );
            }

            update();
        }

        void CNoteGroupView::hoverLeaveEvent ( QGraphicsSceneHoverEvent * )
        {
            mModel->deleteTemporaryNote();

            if ( mModel->getNotes().empty() )
            {
                mModel->getParentBar()->removeNoteGroup(mModel);
            }
        }

        void CNoteGroupView::mousePressEvent ( QGraphicsSceneMouseEvent *event )
        {
            event->ignore();

            if(event->button() == Qt::LeftButton)
            {
                mModel->confirmTempraryNote();
            }
        }

        void CNoteGroupView::update()
        {
            const int u = CGlobals::getUnitSymbolWidth() / 2;

            foreach ( CNote *note, mModel->getNotes() )
            {
                if ( !note->hasView() )
                {
                    note->createView();
                    CNoteView *noteView = note->getView();
                    noteView->initialize();
                    noteView->setParentItem ( this );
                }

                CNoteView *noteView = note->getView();
                noteView->setPos ( ( rect().width() - noteView->rect().width() ) / 2, ( 30 - note->getPosition() ) * u );

            }

            refreshLayout();
        }

        void CNoteGroupView::refreshLayout()
        {
            refreshStemLayout();
        }

        //Protected methods
        /**
            \brief true if stem is up, false if stem is down
        */
        bool CNoteGroupView::getStemDirection()
        {
            return mModel->getLowestNote()->getPosition() <= 14;
        }

        void CNoteGroupView::refreshStemLayout()
        {
            if( mModel->getNoteCount() == 0 )
                return;

            //get lowest & highest note
            CNote *lowestNote = mModel->getLowestNote();
            CNote *highestNote = mModel->getHighestNote();


            for(int i = 0;i < 5; ++i)
            {
                mUpperLines[i].setVisible(mUpperLines[i].boundingRect().y() > highestNote->getView()->pos().y());
                mLowerLines[i].setVisible( mLowerLines[i].boundingRect().y() < lowestNote->getView()->pos().y() + 80);
            }

            if ( ( mModel->getValue() > NOTE_VALUE_HALF )  )
            {
                mStem.setVisible ( false );
                return;
            }


            int y1 = lowestNote->getView()->pos().y() + 25;
            int x = lowestNote->getView()->pos().x();
            int y2 = highestNote->getView()->pos().y() + 40;
            bool stemDirection = getStemDirection();

            if ( stemDirection )
            {
                x += lowestNote->getView()->rect().width() - 10;
                y2 -= 320;
            }
            else
                y1 += 320;

            mStem.setLine ( x, y1 , x, y2 );
            mStem.setVisible ( true );

            NOTE_VALUE val = mModel->getValue();
            for(int cnt = 0;cnt < 5; ++cnt)
            {
                if(val <= NOTE_VALUE_EIGHTH && stemDirection)
                {
                    mRightFlags[cnt].setVisible(true);
                    mRightFlags[cnt].setPos(x,y2 + 50 * cnt);
                }
                else
                {
                    mRightFlags[cnt].setVisible(false);
                }

                if(val <= NOTE_VALUE_EIGHTH && (!stemDirection))
                {
                    mLeftFlags[cnt].setVisible(true);
                    mLeftFlags[cnt].setPos(x - 70,y1 - 150 - (50 * cnt));
                }
                else
                {
                    mLeftFlags[cnt].setVisible(false);
                }

                val *= 2;
            }




        }

        void CNoteGroupView::remove()
        {
            foreach (CNote *note, mModel->getNotes())
                delete note;
            mModel->getNotes().clear();


            update();
        }

        void CNoteGroupView::contextMenuEvent(QGraphicsSceneContextMenuEvent* e)
        {
            mMenu.exec( e->screenPos() );
        }



    }
}
